home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2000 March / maximum-cd-2000-03.iso / Quake3 Game Source / Q3AGameSource.exe / Main / bg_lib.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-01-18  |  27.1 KB  |  1,133 lines

  1. // Copyright (C) 1999-2000 Id Software, Inc.
  2. //
  3. // Copyright (C) 1999-2000 Id Software, Inc.
  4. //
  5. // bg_lib,c -- standard C library replacement routines used by code
  6. // compiled for the virtual machine
  7.  
  8. #include "q_shared.h"
  9.  
  10. /*-
  11.  * Copyright (c) 1992, 1993
  12.  *    The Regents of the University of California.  All rights reserved.
  13.  *
  14.  * Redistribution and use in source and binary forms, with or without
  15.  * modification, are permitted provided that the following conditions
  16.  * are met:
  17.  * 1. Redistributions of source code must retain the above copyright
  18.  *    notice, this list of conditions and the following disclaimer.
  19.  * 2. Redistributions in binary form must reproduce the above copyright
  20.  *    notice, this list of conditions and the following disclaimer in the
  21.  *    documentation and/or other materials provided with the distribution.
  22.  * 3. All advertising materials mentioning features or use of this software
  23.  *    must display the following acknowledgement:
  24.  *    This product includes software developed by the University of
  25.  *    California, Berkeley and its contributors.
  26.  * 4. Neither the name of the University nor the names of its contributors
  27.  *    may be used to endorse or promote products derived from this software
  28.  *    without specific prior written permission.
  29.  *
  30.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  31.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  32.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  33.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  34.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  35.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  36.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  37.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  38.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  39.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  40.  * SUCH DAMAGE.
  41.  */
  42.  
  43. #if defined(LIBC_SCCS) && !defined(lint)
  44. #if 0
  45. static char sccsid[] = "@(#)qsort.c    8.1 (Berkeley) 6/4/93";
  46. #endif
  47. static const char rcsid[] =
  48.     "$Id: bg_lib.c,v 1.7 1999/09/07 20:51:25 zoid Exp $";
  49. #endif /* LIBC_SCCS and not lint */
  50.  
  51. #include <stdlib.h>
  52.  
  53. typedef int         cmp_t(const void *, const void *);
  54. static char    *med3 (char *, char *, char *, cmp_t *);
  55. static void     swapfunc(char *, char *, int, int);
  56.  
  57. #ifndef min
  58. #define min(a, b)    (a) < (b) ? a : b
  59. #endif
  60.  
  61. /*
  62.  * Qsort routine from Bentley & McIlroy's "Engineering a Sort Function".
  63.  */
  64. #define swapcode(TYPE, parmi, parmj, n) {         \
  65.     long i = (n) / sizeof (TYPE);             \
  66.     register TYPE *pi = (TYPE *) (parmi);         \
  67.     register TYPE *pj = (TYPE *) (parmj);         \
  68.     do {                         \
  69.         register TYPE    t = *pi;        \
  70.         *pi++ = *pj;                \
  71.         *pj++ = t;                \
  72.         } while (--i > 0);                \
  73. }
  74.  
  75. #define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \
  76.     es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1;
  77.  
  78. static void
  79. swapfunc(a, b, n, swaptype)
  80.     char *a, *b;
  81.     int n, swaptype;
  82. {
  83.     if(swaptype <= 1)
  84.         swapcode(long, a, b, n)
  85.     else
  86.         swapcode(char, a, b, n)
  87. }
  88.  
  89. #define swap(a, b)                    \
  90.     if (swaptype == 0) {                \
  91.         long t = *(long *)(a);            \
  92.         *(long *)(a) = *(long *)(b);        \
  93.         *(long *)(b) = t;            \
  94.     } else                        \
  95.         swapfunc(a, b, es, swaptype)
  96.  
  97. #define vecswap(a, b, n)     if ((n) > 0) swapfunc(a, b, n, swaptype)
  98.  
  99. static char *
  100. med3(a, b, c, cmp)
  101.     char *a, *b, *c;
  102.     cmp_t *cmp;
  103. {
  104.     return cmp(a, b) < 0 ?
  105.            (cmp(b, c) < 0 ? b : (cmp(a, c) < 0 ? c : a ))
  106.               :(cmp(b, c) > 0 ? b : (cmp(a, c) < 0 ? a : c ));
  107. }
  108.  
  109. void
  110. qsort(a, n, es, cmp)
  111.     void *a;
  112.     size_t n, es;
  113.     cmp_t *cmp;
  114. {
  115.     char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
  116.     int d, r, swaptype, swap_cnt;
  117.  
  118. loop:    SWAPINIT(a, es);
  119.     swap_cnt = 0;
  120.     if (n < 7) {
  121.         for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es)
  122.             for (pl = pm; pl > (char *)a && cmp(pl - es, pl) > 0;
  123.                  pl -= es)
  124.                 swap(pl, pl - es);
  125.         return;
  126.     }
  127.     pm = (char *)a + (n / 2) * es;
  128.     if (n > 7) {
  129.         pl = a;
  130.         pn = (char *)a + (n - 1) * es;
  131.         if (n > 40) {
  132.             d = (n / 8) * es;
  133.             pl = med3(pl, pl + d, pl + 2 * d, cmp);
  134.             pm = med3(pm - d, pm, pm + d, cmp);
  135.             pn = med3(pn - 2 * d, pn - d, pn, cmp);
  136.         }
  137.         pm = med3(pl, pm, pn, cmp);
  138.     }
  139.     swap(a, pm);
  140.     pa = pb = (char *)a + es;
  141.  
  142.     pc = pd = (char *)a + (n - 1) * es;
  143.     for (;;) {
  144.         while (pb <= pc && (r = cmp(pb, a)) <= 0) {
  145.             if (r == 0) {
  146.                 swap_cnt = 1;
  147.                 swap(pa, pb);
  148.                 pa += es;
  149.             }
  150.             pb += es;
  151.         }
  152.         while (pb <= pc && (r = cmp(pc, a)) >= 0) {
  153.             if (r == 0) {
  154.                 swap_cnt = 1;
  155.                 swap(pc, pd);
  156.                 pd -= es;
  157.             }
  158.             pc -= es;
  159.         }
  160.         if (pb > pc)
  161.             break;
  162.         swap(pb, pc);
  163.         swap_cnt = 1;
  164.         pb += es;
  165.         pc -= es;
  166.     }
  167.     if (swap_cnt == 0) {  /* Switch to insertion sort */
  168.         for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es)
  169.             for (pl = pm; pl > (char *)a && cmp(pl - es, pl) > 0;
  170.                  pl -= es)
  171.                 swap(pl, pl - es);
  172.         return;
  173.     }
  174.  
  175.     pn = (char *)a + n * es;
  176.     r = min(pa - (char *)a, pb - pa);
  177.     vecswap(a, pb - r, r);
  178.     r = min(pd - pc, pn - pd - es);
  179.     vecswap(pb, pn - r, r);
  180.     if ((r = pb - pa) > es)
  181.         qsort(a, r / es, es, cmp);
  182.     if ((r = pd - pc) > es) {
  183.         /* Iterate rather than recurse to save stack space */
  184.         a = pn - r;
  185.         n = r / es;
  186.         goto loop;
  187.     }
  188. /*        qsort(pn - r, r / es, es, cmp);*/
  189. }
  190.  
  191. //==================================================================================
  192.  
  193.  
  194. // this file is excluded from release builds because of intrinsics
  195.  
  196. size_t strlen( const char *string ) {
  197.     const char    *s;
  198.  
  199.     s = string;
  200.     while ( *s ) {
  201.         s++;
  202.     }
  203.     return s - string;
  204. }
  205.  
  206.  
  207. char *strcat( char *strDestination, const char *strSource ) {
  208.     char    *s;
  209.  
  210.     s = strDestination;
  211.     while ( *s ) {
  212.         s++;
  213.     }
  214.     while ( *strSource ) {
  215.         *s++ = *strSource++;
  216.     }
  217.     *s = 0;
  218.     return strDestination;
  219. }
  220.  
  221. char *strcpy( char *strDestination, const char *strSource ) {
  222.     char *s;
  223.  
  224.     s = strDestination;
  225.     while ( *strSource ) {
  226.         *s++ = *strSource++;
  227.     }
  228.     *s = 0;
  229.     return strDestination;
  230. }
  231.  
  232.  
  233. int strcmp( const char *string1, const char *string2 ) {
  234.     while ( *string1 == *string2 && *string1 && *string2 ) {
  235.         string1++;
  236.         string2++;
  237.     }
  238.     return *string1 - *string2;
  239. }
  240.  
  241.  
  242. char *strchr( const char *string, int c ) {
  243.     while ( *string ) {
  244.         if ( *string == c ) {
  245.             return ( char * )string;
  246.         }
  247.         string++;
  248.     }
  249.     return (char *)0;
  250. }
  251.  
  252. char *strstr( const char *string, const char *strCharSet ) {
  253.     while ( *string ) {
  254.         int        i;
  255.  
  256.         for ( i = 0 ; strCharSet[i] ; i++ ) {
  257.             if ( string[i] != strCharSet[i] ) {
  258.                 break;
  259.             }
  260.         }
  261.         if ( !strCharSet[i] ) {
  262.             return (char *)string;
  263.         }
  264.         string++;
  265.     }
  266.     return (char *)0;
  267. }
  268.  
  269. #if !defined ( _MSC_VER ) && ! defined ( __linux__ )
  270.  
  271. int tolower( int c ) {
  272.     if ( c >= 'A' && c <= 'Z' ) {
  273.         c += 'a' - 'A';
  274.     }
  275.     return c;
  276. }
  277.  
  278.  
  279. int toupper( int c ) {
  280.     if ( c >= 'a' && c <= 'z' ) {
  281.         c += 'A' - 'a';
  282.     }
  283.     return c;
  284. }
  285.  
  286. #endif
  287. //#ifndef _MSC_VER
  288.  
  289. void *memmove( void *dest, const void *src, size_t count ) {
  290.     int        i;
  291.  
  292.     if ( dest > src ) {
  293.         for ( i = count-1 ; i >= 0 ; i-- ) {
  294.             ((char *)dest)[i] = ((char *)src)[i];
  295.         }
  296.     } else {
  297.         for ( i = 0 ; i < count ; i++ ) {
  298.             ((char *)dest)[i] = ((char *)src)[i];
  299.         }
  300.     }
  301.     return dest;
  302. }
  303.  
  304.  
  305. #if 0
  306.  
  307. double floor( double x ) {
  308.     return (int)(x + 0x40000000) - 0x40000000;
  309. }
  310.  
  311. void *memset( void *dest, int c, size_t count ) {
  312.     while ( count-- ) {
  313.         ((char *)dest)[count] = c;
  314.     }
  315.     return dest;
  316. }
  317.  
  318. void *memcpy( void *dest, const void *src, size_t count ) {
  319.     while ( count-- ) {
  320.         ((char *)dest)[count] = ((char *)src)[count];
  321.     }
  322.     return dest;
  323. }
  324.  
  325. char *strncpy( char *strDest, const char *strSource, size_t count ) {
  326.     char    *s;
  327.  
  328.     s = strDest;
  329.     while ( *strSource && count ) {
  330.         *s++ = *strSource++;
  331.         count--;
  332.     }
  333.     while ( count-- ) {
  334.         *s++ = 0;
  335.     }
  336.     return strDest;
  337. }
  338.  
  339. double sqrt( double x ) {
  340.     float    y;
  341.     float    delta;
  342.     float    maxError;
  343.  
  344.     if ( x <= 0 ) {
  345.         return 0;
  346.     }
  347.  
  348.     // initial guess
  349.     y = x / 2;
  350.  
  351.     // refine
  352.     maxError = x * 0.001;
  353.  
  354.     do {
  355.         delta = ( y * y ) - x;
  356.         y -= delta / ( 2 * y );
  357.     } while ( delta > maxError || delta < -maxError );
  358.  
  359.     return y;
  360. }
  361.  
  362.  
  363. float sintable[1024] = {
  364. 0.000000,0.001534,0.003068,0.004602,0.006136,0.007670,0.009204,0.010738,
  365. 0.012272,0.013805,0.015339,0.016873,0.018407,0.019940,0.021474,0.023008,
  366. 0.024541,0.026075,0.027608,0.029142,0.030675,0.032208,0.033741,0.035274,
  367. 0.036807,0.038340,0.039873,0.041406,0.042938,0.044471,0.046003,0.047535,
  368. 0.049068,0.050600,0.052132,0.053664,0.055195,0.056727,0.058258,0.059790,
  369. 0.061321,0.062852,0.064383,0.065913,0.067444,0.068974,0.070505,0.072035,
  370. 0.073565,0.075094,0.076624,0.078153,0.079682,0.081211,0.082740,0.084269,
  371. 0.085797,0.087326,0.088854,0.090381,0.091909,0.093436,0.094963,0.096490,
  372. 0.098017,0.099544,0.101070,0.102596,0.104122,0.105647,0.107172,0.108697,
  373. 0.110222,0.111747,0.113271,0.114795,0.116319,0.117842,0.119365,0.120888,
  374. 0.122411,0.123933,0.125455,0.126977,0.128498,0.130019,0.131540,0.133061,
  375. 0.134581,0.136101,0.137620,0.139139,0.140658,0.142177,0.143695,0.145213,
  376. 0.146730,0.148248,0.149765,0.151281,0.152797,0.154313,0.155828,0.157343,
  377. 0.158858,0.160372,0.161886,0.163400,0.164913,0.166426,0.167938,0.169450,
  378. 0.170962,0.172473,0.173984,0.175494,0.177004,0.178514,0.180023,0.181532,
  379. 0.183040,0.184548,0.186055,0.187562,0.189069,0.190575,0.192080,0.193586,
  380. 0.195090,0.196595,0.198098,0.199602,0.201105,0.202607,0.204109,0.205610,
  381. 0.207111,0.208612,0.210112,0.211611,0.213110,0.214609,0.216107,0.217604,
  382. 0.219101,0.220598,0.222094,0.223589,0.225084,0.226578,0.228072,0.229565,
  383. 0.231058,0.232550,0.234042,0.235533,0.237024,0.238514,0.240003,0.241492,
  384. 0.242980,0.244468,0.245955,0.247442,0.248928,0.250413,0.251898,0.253382,
  385. 0.254866,0.256349,0.257831,0.259313,0.260794,0.262275,0.263755,0.265234,
  386. 0.266713,0.268191,0.269668,0.271145,0.272621,0.274097,0.275572,0.277046,
  387. 0.278520,0.279993,0.281465,0.282937,0.284408,0.285878,0.287347,0.288816,
  388. 0.290285,0.291752,0.293219,0.294685,0.296151,0.297616,0.299080,0.300543,
  389. 0.302006,0.303468,0.304929,0.306390,0.307850,0.309309,0.310767,0.312225,
  390. 0.313682,0.315138,0.316593,0.318048,0.319502,0.320955,0.322408,0.323859,
  391. 0.325310,0.326760,0.328210,0.329658,0.331106,0.332553,0.334000,0.335445,
  392. 0.336890,0.338334,0.339777,0.341219,0.342661,0.344101,0.345541,0.346980,
  393. 0.348419,0.349856,0.351293,0.352729,0.354164,0.355598,0.357031,0.358463,
  394. 0.359895,0.361326,0.362756,0.364185,0.365613,0.367040,0.368467,0.369892,
  395. 0.371317,0.372741,0.374164,0.375586,0.377007,0.378428,0.379847,0.381266,
  396. 0.382683,0.384100,0.385516,0.386931,0.388345,0.389758,0.391170,0.392582,
  397. 0.393992,0.395401,0.396810,0.398218,0.399624,0.401030,0.402435,0.403838,
  398. 0.405241,0.406643,0.408044,0.409444,0.410843,0.412241,0.413638,0.415034,
  399. 0.416430,0.417824,0.419217,0.420609,0.422000,0.423390,0.424780,0.426168,
  400. 0.427555,0.428941,0.430326,0.431711,0.433094,0.434476,0.435857,0.437237,
  401. 0.438616,0.439994,0.441371,0.442747,0.444122,0.445496,0.446869,0.448241,
  402. 0.449611,0.450981,0.452350,0.453717,0.455084,0.456449,0.457813,0.459177,
  403. 0.460539,0.461900,0.463260,0.464619,0.465976,0.467333,0.468689,0.470043,
  404. 0.471397,0.472749,0.474100,0.475450,0.476799,0.478147,0.479494,0.480839,
  405. 0.482184,0.483527,0.484869,0.486210,0.487550,0.488889,0.490226,0.491563,
  406. 0.492898,0.494232,0.495565,0.496897,0.498228,0.499557,0.500885,0.502212,
  407. 0.503538,0.504863,0.506187,0.507509,0.508830,0.510150,0.511469,0.512786,
  408. 0.514103,0.515418,0.516732,0.518045,0.519356,0.520666,0.521975,0.523283,
  409. 0.524590,0.525895,0.527199,0.528502,0.529804,0.531104,0.532403,0.533701,
  410. 0.534998,0.536293,0.537587,0.538880,0.540171,0.541462,0.542751,0.544039,
  411. 0.545325,0.546610,0.547894,0.549177,0.550458,0.551738,0.553017,0.554294,
  412. 0.555570,0.556845,0.558119,0.559391,0.560662,0.561931,0.563199,0.564466,
  413. 0.565732,0.566996,0.568259,0.569521,0.570781,0.572040,0.573297,0.574553,
  414. 0.575808,0.577062,0.578314,0.579565,0.580814,0.582062,0.583309,0.584554,
  415. 0.585798,0.587040,0.588282,0.589521,0.590760,0.591997,0.593232,0.594466,
  416. 0.595699,0.596931,0.598161,0.599389,0.600616,0.601842,0.603067,0.604290,
  417. 0.605511,0.606731,0.607950,0.609167,0.610383,0.611597,0.612810,0.614022,
  418. 0.615232,0.616440,0.617647,0.618853,0.620057,0.621260,0.622461,0.623661,
  419. 0.624859,0.626056,0.627252,0.628446,0.629638,0.630829,0.632019,0.633207,
  420. 0.634393,0.635578,0.636762,0.637944,0.639124,0.640303,0.641481,0.642657,
  421. 0.643832,0.645005,0.646176,0.647346,0.648514,0.649681,0.650847,0.652011,
  422. 0.653173,0.654334,0.655493,0.656651,0.657807,0.658961,0.660114,0.661266,
  423. 0.662416,0.663564,0.664711,0.665856,0.667000,0.668142,0.669283,0.670422,
  424. 0.671559,0.672695,0.673829,0.674962,0.676093,0.677222,0.678350,0.679476,
  425. 0.680601,0.681724,0.682846,0.683965,0.685084,0.686200,0.687315,0.688429,
  426. 0.689541,0.690651,0.691759,0.692866,0.693971,0.695075,0.696177,0.697278,
  427. 0.698376,0.699473,0.700569,0.701663,0.702755,0.703845,0.704934,0.706021,
  428. 0.707107,0.708191,0.709273,0.710353,0.711432,0.712509,0.713585,0.714659,
  429. 0.715731,0.716801,0.717870,0.718937,0.720003,0.721066,0.722128,0.723188,
  430. 0.724247,0.725304,0.726359,0.727413,0.728464,0.729514,0.730563,0.731609,
  431. 0.732654,0.733697,0.734739,0.735779,0.736817,0.737853,0.738887,0.739920,
  432. 0.740951,0.741980,0.743008,0.744034,0.745058,0.746080,0.747101,0.748119,
  433. 0.749136,0.750152,0.751165,0.752177,0.753187,0.754195,0.755201,0.756206,
  434. 0.757209,0.758210,0.759209,0.760207,0.761202,0.762196,0.763188,0.764179,
  435. 0.765167,0.766154,0.767139,0.768122,0.769103,0.770083,0.771061,0.772036,
  436. 0.773010,0.773983,0.774953,0.775922,0.776888,0.777853,0.778817,0.779778,
  437. 0.780737,0.781695,0.782651,0.783605,0.784557,0.785507,0.786455,0.787402,
  438. 0.788346,0.789289,0.790230,0.791169,0.792107,0.793042,0.793975,0.794907,
  439. 0.795837,0.796765,0.797691,0.798615,0.799537,0.800458,0.801376,0.802293,
  440. 0.803208,0.804120,0.805031,0.805940,0.806848,0.807753,0.808656,0.809558,
  441. 0.810457,0.811355,0.812251,0.813144,0.814036,0.814926,0.815814,0.816701,
  442. 0.817585,0.818467,0.819348,0.820226,0.821103,0.821977,0.822850,0.823721,
  443. 0.824589,0.825456,0.826321,0.827184,0.828045,0.828904,0.829761,0.830616,
  444. 0.831470,0.832321,0.833170,0.834018,0.834863,0.835706,0.836548,0.837387,
  445. 0.838225,0.839060,0.839894,0.840725,0.841555,0.842383,0.843208,0.844032,
  446. 0.844854,0.845673,0.846491,0.847307,0.848120,0.848932,0.849742,0.850549,
  447. 0.851355,0.852159,0.852961,0.853760,0.854558,0.855354,0.856147,0.856939,
  448. 0.857729,0.858516,0.859302,0.860085,0.860867,0.861646,0.862424,0.863199,
  449. 0.863973,0.864744,0.865514,0.866281,0.867046,0.867809,0.868571,0.869330,
  450. 0.870087,0.870842,0.871595,0.872346,0.873095,0.873842,0.874587,0.875329,
  451. 0.876070,0.876809,0.877545,0.878280,0.879012,0.879743,0.880471,0.881197,
  452. 0.881921,0.882643,0.883363,0.884081,0.884797,0.885511,0.886223,0.886932,
  453. 0.887640,0.888345,0.889048,0.889750,0.890449,0.891146,0.891841,0.892534,
  454. 0.893224,0.893913,0.894599,0.895284,0.895966,0.896646,0.897325,0.898001,
  455. 0.898674,0.899346,0.900016,0.900683,0.901349,0.902012,0.902673,0.903332,
  456. 0.903989,0.904644,0.905297,0.905947,0.906596,0.907242,0.907886,0.908528,
  457. 0.909168,0.909806,0.910441,0.911075,0.911706,0.912335,0.912962,0.913587,
  458. 0.914210,0.914830,0.915449,0.916065,0.916679,0.917291,0.917901,0.918508,
  459. 0.919114,0.919717,0.920318,0.920917,0.921514,0.922109,0.922701,0.923291,
  460. 0.923880,0.924465,0.925049,0.925631,0.926210,0.926787,0.927363,0.927935,
  461. 0.928506,0.929075,0.929641,0.930205,0.930767,0.931327,0.931884,0.932440,
  462. 0.932993,0.933544,0.934093,0.934639,0.935184,0.935726,0.936266,0.936803,
  463. 0.937339,0.937872,0.938404,0.938932,0.939459,0.939984,0.940506,0.941026,
  464. 0.941544,0.942060,0.942573,0.943084,0.943593,0.944100,0.944605,0.945107,
  465. 0.945607,0.946105,0.946601,0.947094,0.947586,0.948075,0.948561,0.949046,
  466. 0.949528,0.950008,0.950486,0.950962,0.951435,0.951906,0.952375,0.952842,
  467. 0.953306,0.953768,0.954228,0.954686,0.955141,0.955594,0.956045,0.956494,
  468. 0.956940,0.957385,0.957826,0.958266,0.958703,0.959139,0.959572,0.960002,
  469. 0.960431,0.960857,0.961280,0.961702,0.962121,0.962538,0.962953,0.963366,
  470. 0.963776,0.964184,0.964590,0.964993,0.965394,0.965793,0.966190,0.966584,
  471. 0.966976,0.967366,0.967754,0.968139,0.968522,0.968903,0.969281,0.969657,
  472. 0.970031,0.970403,0.970772,0.971139,0.971504,0.971866,0.972226,0.972584,
  473. 0.972940,0.973293,0.973644,0.973993,0.974339,0.974684,0.975025,0.975365,
  474. 0.975702,0.976037,0.976370,0.976700,0.977028,0.977354,0.977677,0.977999,
  475. 0.978317,0.978634,0.978948,0.979260,0.979570,0.979877,0.980182,0.980485,
  476. 0.980785,0.981083,0.981379,0.981673,0.981964,0.982253,0.982539,0.982824,
  477. 0.983105,0.983385,0.983662,0.983937,0.984210,0.984480,0.984749,0.985014,
  478. 0.985278,0.985539,0.985798,0.986054,0.986308,0.986560,0.986809,0.987057,
  479. 0.987301,0.987544,0.987784,0.988022,0.988258,0.988491,0.988722,0.988950,
  480. 0.989177,0.989400,0.989622,0.989841,0.990058,0.990273,0.990485,0.990695,
  481. 0.990903,0.991108,0.991311,0.991511,0.991710,0.991906,0.992099,0.992291,
  482. 0.992480,0.992666,0.992850,0.993032,0.993212,0.993389,0.993564,0.993737,
  483. 0.993907,0.994075,0.994240,0.994404,0.994565,0.994723,0.994879,0.995033,
  484. 0.995185,0.995334,0.995481,0.995625,0.995767,0.995907,0.996045,0.996180,
  485. 0.996313,0.996443,0.996571,0.996697,0.996820,0.996941,0.997060,0.997176,
  486. 0.997290,0.997402,0.997511,0.997618,0.997723,0.997825,0.997925,0.998023,
  487. 0.998118,0.998211,0.998302,0.998390,0.998476,0.998559,0.998640,0.998719,
  488. 0.998795,0.998870,0.998941,0.999011,0.999078,0.999142,0.999205,0.999265,
  489. 0.999322,0.999378,0.999431,0.999481,0.999529,0.999575,0.999619,0.999660,
  490. 0.999699,0.999735,0.999769,0.999801,0.999831,0.999858,0.999882,0.999905,
  491. 0.999925,0.999942,0.999958,0.999971,0.999981,0.999989,0.999995,0.999999
  492. };
  493.  
  494. double sin( double x ) {
  495.     int    index;
  496.     int    quad;
  497.  
  498.     index = 1024 * x / (M_PI * 0.5);
  499.     quad = ( index >> 10 ) & 3;
  500.     index &= 1023;
  501.     switch ( quad ) {
  502.     case 0:
  503.         return sintable[index];
  504.     case 1:
  505.         return sintable[1023-index];
  506.     case 2:
  507.         return -sintable[index];
  508.     case 3:
  509.         return -sintable[1023-index];
  510.     }
  511.     return 0;
  512. }
  513.  
  514.  
  515. double cos( double x ) {
  516.     int    index;
  517.     int    quad;
  518.  
  519.     index = 1024 * x / (M_PI * 0.5);
  520.     quad = ( index >> 10 ) & 3;
  521.     index &= 1023;
  522.     switch ( quad ) {
  523.     case 3:
  524.         return sintable[index];
  525.     case 0:
  526.         return sintable[1023-index];
  527.     case 1:
  528.         return -sintable[index];
  529.     case 2:
  530.         return -sintable[1023-index];
  531.     }
  532.     return 0;
  533. }
  534.  
  535.  
  536. double atan2( double y, double x ) {
  537.     float    base;
  538.     float    temp;
  539.     float    dir;
  540.     float    test;
  541.     int        i;
  542.  
  543.     if ( x < 0 ) {
  544.         if ( y >= 0 ) {
  545.             // quad 1
  546.             base = M_PI / 2;
  547.             temp = x;
  548.             x = y;
  549.             y = -temp;
  550.         } else {
  551.             // quad 2
  552.             base = M_PI;
  553.             x = -x;
  554.             y = -y;
  555.         }
  556.     } else {
  557.         if ( y < 0 ) {
  558.             // quad 3
  559.             base = 3 * M_PI / 2;
  560.             temp = x;
  561.             x = -y;
  562.             y = temp;
  563.         }
  564.     }
  565.  
  566.     if ( y > x ) {
  567.         base += M_PI/2;
  568.         temp = x;
  569.         x = y;
  570.         y = temp;
  571.         dir = -1;
  572.     } else {
  573.         dir = 1;
  574.     }
  575.  
  576.     // calcualte angle in octant 0
  577.     if ( x == 0 ) {
  578.         return base;
  579.     }
  580.     y /= x;
  581.  
  582.     for ( i = 0 ; i < 512 ; i++ ) {
  583.         test = sintable[i] / sintable[1023-i];
  584.         if ( test > y ) {
  585.             break;
  586.         }
  587.     }
  588.  
  589.     return base + dir * i * ( M_PI/2048); 
  590. }
  591.  
  592.  
  593. #endif
  594.  
  595. double tan( double x ) {
  596.     return sin(x) / cos(x);
  597. }
  598.  
  599.  
  600. static int randSeed = 0;
  601.  
  602. void    srand( unsigned seed ) {
  603.     randSeed = seed;
  604. }
  605.  
  606. int        rand( void ) {
  607.     randSeed = (69069 * randSeed + 1);
  608.     return randSeed & 0x7fff;
  609. }
  610.  
  611. double atof( const char *string ) {
  612.     float sign;
  613.     float value;
  614.     int        c;
  615.  
  616.  
  617.     // skip whitespace
  618.     while ( *string <= ' ' ) {
  619.         if ( !*string ) {
  620.             return 0;
  621.         }
  622.         string++;
  623.     }
  624.  
  625.     // check sign
  626.     switch ( *string ) {
  627.     case '+':
  628.         string++;
  629.         sign = 1;
  630.         break;
  631.     case '-':
  632.         string++;
  633.         sign = -1;
  634.         break;
  635.     default:
  636.         sign = 1;
  637.         break;
  638.     }
  639.  
  640.     // read digits
  641.     value = 0;
  642.     c = string[0];
  643.     if ( c != '.' ) {
  644.         do {
  645.             c = *string++;
  646.             if ( c < '0' || c > '9' ) {
  647.                 break;
  648.             }
  649.             c -= '0';
  650.             value = value * 10 + c;
  651.         } while ( 1 );
  652.     } else {
  653.         string++;
  654.     }
  655.  
  656.     // check for decimal point
  657.     if ( c == '.' ) {
  658.         double fraction;
  659.  
  660.         fraction = 0.1;
  661.         do {
  662.             c = *string++;
  663.             if ( c < '0' || c > '9' ) {
  664.                 break;
  665.             }
  666.             c -= '0';
  667.             value += c * fraction;
  668.             fraction *= 0.1;
  669.         } while ( 1 );
  670.  
  671.     }
  672.  
  673.     // not handling 10e10 notation...
  674.  
  675.     return value * sign;
  676. }
  677.  
  678. double _atof( const char **stringPtr ) {
  679.     const char    *string;
  680.     float sign;
  681.     float value;
  682.     int        c;
  683.  
  684.     string = *stringPtr;
  685.  
  686.     // skip whitespace
  687.     while ( *string <= ' ' ) {
  688.         if ( !*string ) {
  689.             *stringPtr = string;
  690.             return 0;
  691.         }
  692.         string++;
  693.     }
  694.  
  695.     // check sign
  696.     switch ( *string ) {
  697.     case '+':
  698.         string++;
  699.         sign = 1;
  700.         break;
  701.     case '-':
  702.         string++;
  703.         sign = -1;
  704.         break;
  705.     default:
  706.         sign = 1;
  707.         break;
  708.     }
  709.  
  710.     // read digits
  711.     value = 0;
  712.     if ( string[0] != '.' ) {
  713.         do {
  714.             c = *string++;
  715.             if ( c < '0' || c > '9' ) {
  716.                 break;
  717.             }
  718.             c -= '0';
  719.             value = value * 10 + c;
  720.         } while ( 1 );
  721.     }
  722.  
  723.     // check for decimal point
  724.     if ( c == '.' ) {
  725.         double fraction;
  726.  
  727.         fraction = 0.1;
  728.         do {
  729.             c = *string++;
  730.             if ( c < '0' || c > '9' ) {
  731.                 break;
  732.             }
  733.             c -= '0';
  734.             value += c * fraction;
  735.             fraction *= 0.1;
  736.         } while ( 1 );
  737.  
  738.     }
  739.  
  740.     // not handling 10e10 notation...
  741.     *stringPtr = string;
  742.  
  743.     return value * sign;
  744. }
  745.  
  746.  
  747. #if !defined( _MSC_VER ) && !defined( __linux__ )
  748.  
  749. int atoi( const char *string ) {
  750.     int        sign;
  751.     int        value;
  752.     int        c;
  753.  
  754.  
  755.     // skip whitespace
  756.     while ( *string <= ' ' ) {
  757.         if ( !*string ) {
  758.             return 0;
  759.         }
  760.         string++;
  761.     }
  762.  
  763.     // check sign
  764.     switch ( *string ) {
  765.     case '+':
  766.         string++;
  767.         sign = 1;
  768.         break;
  769.     case '-':
  770.         string++;
  771.         sign = -1;
  772.         break;
  773.     default:
  774.         sign = 1;
  775.         break;
  776.     }
  777.  
  778.     // read digits
  779.     value = 0;
  780.     do {
  781.         c = *string++;
  782.         if ( c < '0' || c > '9' ) {
  783.             break;
  784.         }
  785.         c -= '0';
  786.         value = value * 10 + c;
  787.     } while ( 1 );
  788.  
  789.     // not handling 10e10 notation...
  790.  
  791.     return value * sign;
  792. }
  793.  
  794.  
  795. int _atoi( const char **stringPtr ) {
  796.     int        sign;
  797.     int        value;
  798.     int        c;
  799.     const char    *string;
  800.  
  801.     string = *stringPtr;
  802.  
  803.     // skip whitespace
  804.     while ( *string <= ' ' ) {
  805.         if ( !*string ) {
  806.             return 0;
  807.         }
  808.         string++;
  809.     }
  810.  
  811.     // check sign
  812.     switch ( *string ) {
  813.     case '+':
  814.         string++;
  815.         sign = 1;
  816.         break;
  817.     case '-':
  818.         string++;
  819.         sign = -1;
  820.         break;
  821.     default:
  822.         sign = 1;
  823.         break;
  824.     }
  825.  
  826.     // read digits
  827.     value = 0;
  828.     do {
  829.         c = *string++;
  830.         if ( c < '0' || c > '9' ) {
  831.             break;
  832.         }
  833.         c -= '0';
  834.         value = value * 10 + c;
  835.     } while ( 1 );
  836.  
  837.     // not handling 10e10 notation...
  838.  
  839.     *stringPtr = string;
  840.  
  841.     return value * sign;
  842. }
  843.  
  844. int abs( int n ) {
  845.     return n < 0 ? -n : n;
  846. }
  847.  
  848. double fabs( double x ) {
  849.     return x < 0 ? -x : x;
  850. }
  851.  
  852.  
  853.  
  854. //=========================================================
  855.  
  856.  
  857. #define ALT            0x00000001        /* alternate form */
  858. #define HEXPREFIX    0x00000002        /* add 0x or 0X prefix */
  859. #define LADJUST        0x00000004        /* left adjustment */
  860. #define LONGDBL        0x00000008        /* long double */
  861. #define LONGINT        0x00000010        /* long integer */
  862. #define QUADINT        0x00000020        /* quad integer */
  863. #define SHORTINT    0x00000040        /* short integer */
  864. #define ZEROPAD        0x00000080        /* zero (as opposed to blank) pad */
  865. #define FPT            0x00000100        /* floating point number */
  866.  
  867. #define to_digit(c)        ((c) - '0')
  868. #define is_digit(c)        ((unsigned)to_digit(c) <= 9)
  869. #define to_char(n)        ((n) + '0')
  870.  
  871. void AddInt( char **buf_p, int val, int width, int flags ) {
  872.     char    text[32];
  873.     int        digits;
  874.     int        signedVal;
  875.     char    *buf;
  876.  
  877.     digits = 0;
  878.     signedVal = val;
  879.     if ( val < 0 ) {
  880.         val = -val;
  881.     }
  882.     do {
  883.         text[digits++] = '0' + val % 10;
  884.         val /= 10;
  885.     } while ( val );
  886.  
  887.     if ( signedVal < 0 ) {
  888.         text[digits++] = '-';
  889.     }
  890.  
  891.     buf = *buf_p;
  892.  
  893.     if( !( flags & LADJUST ) ) {
  894.         while ( digits < width ) {
  895.             *buf++ = ( flags & ZEROPAD ) ? '0' : ' ';
  896.             width--;
  897.         }
  898.     }
  899.  
  900.     while ( digits-- ) {
  901.         *buf++ = text[digits];
  902.         width--;
  903.     }
  904.  
  905.     if( flags & LADJUST ) {
  906.         while ( width-- ) {
  907.             *buf++ = ( flags & ZEROPAD ) ? '0' : ' ';
  908.         }
  909.     }
  910.  
  911.     *buf_p = buf;
  912. }
  913.  
  914. void AddFloat( char **buf_p, float fval, int width, int prec ) {
  915.     char    text[32];
  916.     int        digits;
  917.     float    signedVal;
  918.     char    *buf;
  919.     int        val;
  920.  
  921.     // FIXME!!!! handle fractions
  922.  
  923.     digits = 0;
  924.     signedVal = fval;
  925.     if ( fval < 0 ) {
  926.         fval = -fval;
  927.     }
  928.  
  929.     val = (int)fval;
  930.     do {
  931.         text[digits++] = '0' + val % 10;
  932.         val /= 10;
  933.     } while ( val );
  934.  
  935.     if ( signedVal < 0 ) {
  936.         text[digits++] = '-';
  937.     }
  938.  
  939.     buf = *buf_p;
  940.  
  941.     while ( digits < width ) {
  942.         *buf++ = ' ';
  943.         width--;
  944.     }
  945.  
  946.     while ( digits-- ) {
  947.         *buf++ = text[digits];
  948.     }
  949.  
  950.     *buf_p = buf;
  951. }
  952.  
  953.  
  954. void AddString( char **buf_p, char *string, int width, int prec ) {
  955.     int        size;
  956.     char    *buf;
  957.  
  958.     buf = *buf_p;
  959.  
  960.     if ( string == NULL ) {
  961.         string = "(null)";
  962.         prec = -1;
  963.     }
  964.  
  965.     if ( prec >= 0 ) {
  966.         for( size = 0; size < prec; size++ ) {
  967.             if( string[size] == '\0' ) {
  968.                 break;
  969.             }
  970.         }
  971.     }
  972.     else {
  973.         size = strlen( string );
  974.     }
  975.  
  976.     width -= size;
  977.  
  978.     while( size-- ) {
  979.         *buf++ = *string++;
  980.     }
  981.  
  982.     while( width-- > 0 ) {
  983.         *buf++ = ' ';
  984.     }
  985.  
  986.     *buf_p = buf;
  987. }
  988.  
  989. /*
  990. vsprintf
  991.  
  992. I'm not going to support a bunch of the more arcane stuff in here
  993. just to keep it simpler.  For example, the '*' and '$' are not
  994. currently supported.  I've tried to make it so that it will just
  995. parse and ignore formats we don't support.
  996. */
  997. int vsprintf( char *buffer, const char *fmt, va_list argptr ) {
  998.     int        *arg;
  999.     char    *buf_p;
  1000.     char    ch;
  1001.     int        flags;
  1002.     int        width;
  1003.     int        prec;
  1004.     int        n;
  1005.     char    sign;
  1006.  
  1007.     buf_p = buffer;
  1008.     arg = (int *)argptr;
  1009.  
  1010.     while( qtrue ) {
  1011.         // run through the format string until we hit a '%' or '\0'
  1012.         for ( ch = *fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++ ) {
  1013.             *buf_p++ = ch;
  1014.         }
  1015.         if ( ch == '\0' ) {
  1016.             goto done;
  1017.         }
  1018.  
  1019.         // skip over the '%'
  1020.         fmt++;
  1021.  
  1022.         // reset formatting state
  1023.         flags = 0;
  1024.         width = 0;
  1025.         prec = -1;
  1026.         sign = '\0';
  1027.  
  1028. rflag:
  1029.         ch = *fmt++;
  1030. reswitch:
  1031.         switch( ch ) {
  1032.         case '-':
  1033.             flags |= LADJUST;
  1034.             goto rflag;
  1035.         case '.':
  1036.             n = 0;
  1037.             while( is_digit( ( ch = *fmt++ ) ) ) {
  1038.                 n = 10 * n + ( ch - '0' );
  1039.             }
  1040.             prec = n < 0 ? -1 : n;
  1041.             goto reswitch;
  1042.         case '0':
  1043.             flags |= ZEROPAD;
  1044.             goto rflag;
  1045.         case '1':
  1046.         case '2':
  1047.         case '3':
  1048.         case '4':
  1049.         case '5':
  1050.         case '6':
  1051.         case '7':
  1052.         case '8':
  1053.         case '9':
  1054.             n = 0;
  1055.             do {
  1056.                 n = 10 * n + ( ch - '0' );
  1057.                 ch = *fmt++;
  1058.             } while( is_digit( ch ) );
  1059.             width = n;
  1060.             goto reswitch;
  1061.         case 'c':
  1062.             *buf_p++ = (char)*arg;
  1063.             arg++;
  1064.             break;
  1065.         case 'd':
  1066.         case 'i':
  1067.             AddInt( &buf_p, *arg, width, flags );
  1068.             arg++;
  1069.             break;
  1070.         case 'f':
  1071.             AddFloat( &buf_p, *(double *)arg, width, prec );
  1072. #ifdef __LCC__
  1073.             arg += 1;    // everything is 32 bit in my compiler
  1074. #else
  1075.             arg += 2;
  1076. #endif
  1077.             break;
  1078.         case 's':
  1079.             AddString( &buf_p, (char *)*arg, width, prec );
  1080.             arg++;
  1081.             break;
  1082.         case '%':
  1083.             *buf_p++ = ch;
  1084.             break;
  1085.         default:
  1086.             *buf_p++ = (char)*arg;
  1087.             arg++;
  1088.             break;
  1089.         }
  1090.     }
  1091.  
  1092. done:
  1093.     *buf_p = 0;
  1094.     return buf_p - buffer;
  1095. }
  1096.  
  1097.  
  1098. /* this is really crappy */
  1099. int sscanf( const char *buffer, const char *fmt, ... ) {
  1100.     int        cmd;
  1101.     int        **arg;
  1102.     int        count;
  1103.  
  1104.     arg = (int **)&fmt + 1;
  1105.     count = 0;
  1106.  
  1107.     while ( *fmt ) {
  1108.         if ( fmt[0] != '%' ) {
  1109.             fmt++;
  1110.             continue;
  1111.         }
  1112.  
  1113.         cmd = fmt[1];
  1114.         fmt += 2;
  1115.  
  1116.         switch ( cmd ) {
  1117.         case 'i':
  1118.         case 'd':
  1119.         case 'u':
  1120.             **arg = _atoi( &buffer );
  1121.             break;
  1122.         case 'f':
  1123.             *(float *)*arg = _atof( &buffer );
  1124.             break;
  1125.         }
  1126.         arg++;
  1127.     }
  1128.  
  1129.     return count;
  1130. }
  1131.  
  1132. #endif
  1133.